#!perl
use Test::More tests => 6;
use lib 't';
use Wx::Perl::SimpleThread;

use WxTesting qw( app_from_wxtesting_frame );

my $app = app_from_wxtesting_frame( 'SimpleThreadTestingFrame' );
$app->MainLoop;

package SimpleThreadTestingFrame;
use strict;
use base qw(WxTesting::Frame);
use Test::More;
use Wx qw( wxTheApp );
use Time::HiRes qw( sleep );
use Wx::Perl::SimpleThread::Handler::Event qw( :all );

sub new {
    my $class = shift;
    my $self = $class->SUPER::new( undef, -1, 'Testing Wx::Perl::SimpleThread DoScript');
    EVT_WXP_SIMPLE_THREAD_DATA( $self, \&evt_process);
    EVT_WXP_SIMPLE_THREAD_REQUEST_COMPLETE( $self, \&evt_process);
    EVT_WXP_SIMPLE_THREAD_EXIT(   $self, \&evt_process);
    $self->reset;
    #$self->Show(1);
    return $self;
}

sub reset {
    my $self = shift;
    $self->{_stdout} = [];
    $self->{_stderr} = [];
    $self->{_complete} = undef;
}

sub RunTests {
    my $self = shift;
    my $threadmodule = 'Wx::Perl::SimpleThread::Thread::DoScript';
    
    
    my $handler = Wx::Perl::SimpleThread::Handler::Event->new($threadmodule, $self);
    # $handler must stay in scope - the child thread is shut down when the handler
    # goes out of scope
    
    $self->reset;
    $handler->send_thread_request({ script => 'testdoscript.pl', args => [ qw( 1 4 8 5 ) ] });
    $self->wait_for_test_complete;
    is( $self->{_stderr}->[0], 'The argument count was : 4 at t/testdoscript.pl line 1.', 'doscript stderr');
    is( $self->{_stdout}->[0], 'My arguments are : 1, 4, 8, 5', 'doscript stdout');
    is( $self->{_complete}->[0], 'SUCCESS', 'doscript complete return');
    
    $self->reset;
    $handler->send_thread_request({ script => 'testdoscript.pl', args => [ qw( hello goodbye ) ] });
    $self->wait_for_test_complete;
    is( $self->{_stderr}->[0], 'The argument count was : 2 at t/testdoscript.pl line 1.', 'doscript stderr');
    is( $self->{_stdout}->[0], 'My arguments are : hello, goodbye', 'doscript stdout');
    is( $self->{_complete}->[0], 'SUCCESS', 'doscript complete return');
}

sub wait_for_test_complete {
    my $self = shift;
    while(!$self->{_complete}) {
        $app->Yield();
        sleep 0.1;
    }
}

sub evt_process {
    my ($self, $event) = @_;
    $event->Skip(1);
    #diag 'EVT PROCESS CALLED';
    my $evttype = $event->GetEventType();
    #diag qq(event type = $evttype);
    my $tid = $event->GetThreadId();
    #diag qq(event tid = $tid);
    
       
    if($evttype == wxpEVT_SIMPLE_THREAD_DATA) {
	#diag qq(EVT DATA CALLED);
	my $data = $event->GetClientData();
	my $output = $data->{data};
	chomp($output) if $output;;
	if($data->{stream} eq 'stdout') {
	    push(@{ $self->{_stdout} }, $output);
	} else {
	    push(@{ $self->{_stderr} }, $output);
	}
    } elsif ( $evttype == wxpEVT_SIMPLE_THREAD_REQUEST_COMPLETE) {
	#diag qq(EVT COMPLETE CALLED);
	my $data = $event->GetClientData();
	if( $data->{errorflag} == 0 ) {
	    $self->{_complete} = [ 'SUCCESS' ];
	} else {
	    my $errors = $data->{errors} || 'UNKNOWN ERROR';
	    chomp($errors);
	    $self->{_complete} = [ $errors ];
	}
    } elsif ( $evttype == wxpEVT_SIMPLE_THREAD_EXIT) {
       #diag qq(EVT EXIT CALLED);
       $self->{_completed} = [] if !$self->{_completed};
       push( @{ $self->{_completed} }, 'EXIT EVENT CALLED' );
    }
}


1;

